extern crate fejpsl_contract;

use self::fejpsl_contract::community::room::{RoomPageData, Room, RoomListData, RoomKey, RoomKeyData, RoomData};
use chrono::{DateTime, Local};
use self::fejpsl_contract::community::member::{Member, MemberData};

pub async fn get_my_room_list_by_page_no(page_no:&i32,user_uuid:&String) ->RoomPageData {
    let client = super::super::db::connect().await.unwrap();
    let mut vec_room = Vec::new();
    let per_page_num:i64=10;
    let offset:i64;
    offset=*page_no as i64 *per_page_num;
    let rows = &client.query("SELECT id,room_name, room_desc, admin_uuid, table_num,admin_name,member_num FROM
 (select a.*,b.member_num from t_room a left join (SELECT room_id,count(room_id) member_num from t_room_member
	group by room_id) b on a.id=b.room_id and a.admin_uuid=$3) c
		left join (SELECT user_uuid,case when is_explicit=1 then nice_name else real_name end admin_name from t_user) d
		on c.admin_uuid=d.user_uuid where admin_uuid=$3 limit $1 offset $2",
                             &[&per_page_num,&offset,&user_uuid]).await.unwrap();
    for row in rows {
        let mut m_member_num=0;
        let tmp_str: Option<i64> = row.get(6);
        if let Some(_i) = tmp_str {m_member_num= row.get(6); }else{ m_member_num=0}
        let room = Room {
            id:                 row.get(0),
            room_name:          row.get(1),
            room_desc:    row.get(2),
            admin_uuid:        row.get(3),
            table_num:            row.get(4),
            admin_name:           row.get(5),
            member_num:        m_member_num,
        };

        vec_room.push(room);
    }

    let total=rows.len() as i32;
    let page_count=(total/10) as i32;
    let mut over=false;
    if page_no>=&page_count {over=true}
    let size=per_page_num as i32;
    let room_list_data= RoomListData {
        cur_page:*page_no,
        datas:Some(vec_room),
        offset: offset,
        over: over,
        page_count:page_count,
        size:size,
        total:total,
    };
    let room_page_data= RoomPageData {
        data:room_list_data,
        error_code: 0,
        error_msg:"Success.".to_string(),
    };
    return room_page_data;

}

pub async fn get_hot_room_list_by_page_no(page_no:&i32) ->RoomPageData {
    let client = super::super::db::connect().await.unwrap();
    let mut vec_room = Vec::new();
    let per_page_num:i64=10;
    let offset:i64;
    offset=*page_no as i64 *per_page_num;
    let rows = &client.query("SELECT id,room_name, room_desc, admin_uuid, table_num,admin_name,member_num FROM
 (select a.*,b.member_num from t_room a left join (SELECT room_id,count(room_id) member_num from t_room_member
	group by room_id) b on a.id=b.room_id) c
		left join (SELECT user_uuid,case when is_explicit=1 then nice_name else real_name end admin_name from t_user) d
		on c.admin_uuid=d.user_uuid order by member_num desc limit $1 offset $2",
                             &[&per_page_num,&offset]).await.unwrap();
    for row in rows {
        let mut m_member_num=0;
        let tmp_str: Option<i64> = row.get(6);
        if let Some(_i) = tmp_str {m_member_num= row.get(6); }else{ m_member_num=0}
        let room = Room {
            id:                 row.get(0),
            room_name:          row.get(1),
            room_desc:    row.get(2),
            admin_uuid:        row.get(3),
            table_num:            row.get(4),
            admin_name:           row.get(5),
            member_num:        m_member_num,
        };

        vec_room.push(room);
    }

    let total=rows.len() as i32;
    let page_count=(total/10) as i32;
    let mut over=false;
    if page_no>=&page_count {over=true}
    let size=per_page_num as i32;
    let room_list_data= RoomListData {
        cur_page:*page_no,
        datas:Some(vec_room),
        offset: offset,
        over: over,
        page_count:page_count,
        size:size,
        total:total,
    };
    let room_page_data= RoomPageData {
        data:room_list_data,
        error_code: 0,
        error_msg:"Success.".to_string(),
    };
    return room_page_data;

}

pub async fn create_room(user_uuid:&String) -> RoomKeyData {
    let client = super::super::db::connect().await.unwrap();
    let rows = &client.query("SELECT id,room_name, room_desc, admin_uuid, table_num from t_room where admin_uuid=$1", &[&user_uuid]).await.unwrap();
    let count  = rows.len();
    let mut copper_cash:i32=10000; //create room fee
    if count>0{
        copper_cash=10000+count as i32*20000;
    }
    let rows = &client.query("SELECT case when is_explicit=1 then nice_name else real_name end admin_name,copper_cash from t_user where user_uuid=$1", &[&user_uuid]).await.unwrap();
    let count  = rows.len();
    let mut room_name="".to_string();
    let mut my_copper_cash:i64=0;
    if count>0{
        let admin_name:&str=rows[0].get("admin_name") ;
        room_name=admin_name.to_string()+"的房间"+&(count+1).to_string();
        my_copper_cash=rows[0].get("copper_cash")
    }
    let local: DateTime<Local> = Local::now(); // 本地时间
    println!(
        " date 精确到毫秒 ({:?})",
        local.format("%Y-%m-%d %H:%M:%S%.3f").to_string()
    );
    //let admin_uuid=user_uuid;
    //let copper_cash=room_fee;
    let room_desc="公告".to_string();
    let create_time=local.format("%Y-%m-%d %H:%M:%S%.3f").to_string();
    let deleted=false;
    let table_num=5;

    let _row = client.query("INSERT INTO t_room (room_name,admin_uuid,copper_cash,room_desc,create_time,update_time,\
        deleted,table_num) VALUES($1,$2,$3,$4,$5,$6,$7,$8)",
                            &[&room_name,&user_uuid,&copper_cash,&room_desc,&create_time,&create_time,&deleted,&table_num]).await.unwrap();

    my_copper_cash=my_copper_cash-copper_cash as i64;

    let rows = &client.query("SELECT id,room_name, room_desc, admin_uuid, table_num from t_room where admin_uuid=$1 order by id desc", &[&user_uuid]).await.unwrap();
    let room_id=rows[0].get(0);
    let roomKey = RoomKey {
        id:               room_id ,
        room_name:          room_name.to_string(),
        room_desc:      "公告".to_string(),
        admin_uuid:        user_uuid.to_string(),
        table_num:            5,
        admin_name:           "".to_string(),
        member_num:        1,
        my_room_num:   count as i32+1,
        my_copper_cash :my_copper_cash as i64,
    };

    let _row = client.query("UPDATE t_user set copper_cash=$2 where user_uuid=$1",
                            &[&user_uuid,&my_copper_cash]).await.unwrap();

    let is_blacked=0;
    let allow_speak=1;
    let _row = client.query("INSERT INTO t_room_member (room_id,user_uuid,is_blacked,allow_speak,create_time,update_time\
        ) VALUES($1,$2,$3,$4,$5,$6)",
                            &[&room_id,&user_uuid,&is_blacked,&allow_speak,&create_time,&create_time]).await.unwrap();

    let table_desc="".to_string();
    let is_encrypted=0;
    let table_password="".to_string();
    for table_no in 1..5{
        let _row = client.query("INSERT INTO t_room_table (room_id,table_no,table_desc,is_encrypted,table_password,create_time,update_time\
        ) VALUES($1,$2,$3,$4,$5,$6,$7)",
                                &[&room_id,&table_no,&table_desc,&is_encrypted,&table_password,&create_time,&create_time]).await.unwrap();
    }

    let result_data= RoomKeyData {
        data: Some(roomKey),
        error_code: 0,
        error_msg:"Success.".to_string(),
    };
    return result_data;
}
pub async fn join_room(room_id:&i32,user_uuid:&String) -> MemberData {
    let client = super::super::db::connect().await.unwrap();

    let member = Member {
        id:                 0,
        room_id:         *room_id,
        user_uuid:       user_uuid.to_string(),
        is_blacked:       0,
        allow_speak:       1
    };
    let rows = &client.query("SELECT id,room_name from t_room where id=$1",
                            &[&room_id]).await.unwrap();
    let count  = rows.len();
    if count==0{
        let result_data= MemberData {
            data: Some(member),
            error_code: 1,
            error_msg:"房间号不存在.".to_string(),
        };
        return result_data;
    }
    let rows = &client.query("SELECT id from t_room_member where room_id=$1 and user_uuid=$2",
                             &[&room_id,&user_uuid]).await.unwrap();
    let count  = rows.len();
    if count>0{
        let result_data= MemberData {
            data: Some(member),
            error_code: 0,
            error_msg:"房间已加入.".to_string(),
        };
        return result_data;
    }

    let local: DateTime<Local> = Local::now(); // 本地时间
    println!(
        " date 精确到毫秒 ({:?})",
        local.format("%Y-%m-%d %H:%M:%S%.3f").to_string()
    );
    let create_time=local.format("%Y-%m-%d %H:%M:%S%.3f").to_string();
    let is_blacked=0;
    let allow_speak=1;

    let _row = client.query("INSERT INTO t_room_member (room_id,user_uuid,is_blacked,allow_speak,create_time,update_time\
        ) VALUES($1,$2,$3,$4,$5,$6)",
                            &[&room_id,&user_uuid,&is_blacked,&allow_speak,&create_time,&create_time]).await.unwrap();


    let result_data= MemberData {
        data: Some(member),
        error_code: 0,
        error_msg:"Success.".to_string(),
    };
    return result_data;

}
pub async fn delete_room(room_id:&i32,user_uuid:&String) -> RoomData {
    let client = super::super::db::connect().await.unwrap();

    let _row = client.query("delete from t_room where room_id=$1 and admin_uuid=$2",
                            &[&room_id,&user_uuid]).await.unwrap();

    let room = Room {
        id:                 0,
        room_name:        "".to_string(),
        room_desc:       "".to_string(),
        admin_name:       "".to_string(),
        admin_uuid:      "".to_string(),
        table_num:   0,
        member_num:  0,
    };
    let result_data= RoomData {
        data: Some(room),
        error_code: 0,
        error_msg:"Success.".to_string(),
    };
    return result_data;
}